﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;

public class LevelFirst : MonoBehaviour {
    public CameraAnimation cameraAnimation;
    public DoorAnimation doorAnimation;
    public MenuAnimation menuAnimation;
    public WaypointAnimation roleWaypointAnimation;
    public WaypointAnimation lediWaypointAnimation;
    public Transform roleRoot;
    public Transform uiRoot;
    public Transform dishRoot;
    public Transform gameDoneEffect;
    public GameObject hand;


    float _delay = 3f;
    float _shakeInterval = 3f;
    int _roleCount = 3;
    RoleAnimation _roleAnimation;
    LeDiAnimation _lediAnimation;
    Transform _btnLeft;
    Transform _btnRight;

	void Init() {
        _btnLeft = uiRoot.Find("Btn_Left");
        _btnRight = uiRoot.Find("Btn_Right");
        _lediAnimation = lediWaypointAnimation.GetComponentInChildren<LeDiAnimation>();
    }

    public void Forward() {
        Init();
        SpawnRole();

        lediWaypointAnimation.Forward();
        roleWaypointAnimation.Forward();

        StartCoroutine(TimeUtility.DelayInvoke(_delay, () => {
            doorAnimation.Open(ChineseRestaurantResPath.SFX_DOOR_WOOD).OnFinished(RoleWalk);
            StartCoroutine(TimeUtility.DelayInvoke(_delay, () => doorAnimation.Close(ChineseRestaurantResPath.SFX_DOOR_WOOD)));
        }));
    }

    // ===================== Reverse =====================
    public void Reverse() {
        Init();
        SpawnRole(false);

        menuAnimation.transform.parent.SetActive(false);
        lediWaypointAnimation.Reverse();
        roleWaypointAnimation.Reverse();

        var lediWaypoints = lediWaypointAnimation.waypoints;
        var lediTarget = lediWaypoints[lediWaypoints.Length - 1].target;
        lediWaypointAnimation.transform.position = lediTarget.position;
        lediWaypointAnimation.transform.rotation = lediTarget.rotation;

        var path = ChineseRestaurantResPath.PREFAB_DIR + "Dish_" + ChineseRestaurantManager.Instance.currentDishName.ToString();
        var dish = CommonUtility.InstantiateFrom(path, lediWaypointAnimation.transform);

        var roleWaypoints = roleWaypointAnimation.waypoints;
        var roleTarget = roleWaypoints[roleWaypoints.Length - 1].target;
        roleWaypointAnimation.transform.position = roleTarget.position;
        roleWaypointAnimation.transform.rotation = roleTarget.rotation;

        _roleAnimation.SitIdle();
        _lediAnimation.Carry();

        lediWaypointAnimation.ToNext(() => {
            _lediAnimation.Idle();
            AudioManager.Instance.PlaySound(ChineseRestaurantResPath.SFX_SERVING_DISHES);
            dish.DOMove(dishRoot.position, 1f).OnComplete(() => {
                dish.SetParent(dishRoot);
                cameraAnimation.Forward().OnFinished(() => {
                    _roleAnimation.Praise(ChineseRestaurantManager.Instance.GetVoicePathFrom(RoleState.ServingDishes), () => {
                        dish.gameObject.AddComponent<DragDishes>();
                    });
                });
            });
        });
    }

    public void Leave() {
        _roleAnimation.SitDown().OnFinished(() => {
            roleWaypointAnimation.ToEnd();

            var voicePaths = new string[] {
                ChineseRestaurantResPath.LEDI_404040426,
                ChineseRestaurantResPath.LEDI_404040427,
                ChineseRestaurantResPath.LEDI_404040428
            };

            AudioManager.Instance.PlaySound(voicePaths[Random.Range(0, voicePaths.Length)]);
            _lediAnimation.Walk();
            lediWaypointAnimation.ToEnd(() => {
                lediWaypointAnimation.transform.DOLocalRotate(new Vector3(0f, 21.35f, 0f), 0.5f).OnComplete(() => {
                    _lediAnimation.Idle();
                });
            });

            StartCoroutine(TimeUtility.DelayInvoke(_delay, () => doorAnimation.Open(ChineseRestaurantResPath.SFX_DOOR_WOOD).OnFinished(() => {
                StartCoroutine(TimeUtility.DelayInvoke(_delay, () => doorAnimation.Close(ChineseRestaurantResPath.SFX_DOOR_WOOD).OnFinished(() => {
                    Destroy(roleRoot.GetChild(0).gameObject);

                    foreach (Transform child in dishRoot) {
                        child.GetComponent<EventBehaviour>().Hide();
                    }

                    // 游戏完成
                    GameDone();

                    StartCoroutine(TimeUtility.DelayInvoke(_delay, () => {
                        menuAnimation.transform.parent.SetActive(true);
                        Forward();
                    }));
                })));
            })));
        });
    }

    void GameDone() {
        var duration = AudioManager.Instance.PlaySound(ChineseRestaurantResPath.SFX_GAME_DONE).Length;
        SetGameDoneEffect(true);
        StartCoroutine(TimeUtility.DelayInvoke(duration, () => SetGameDoneEffect(false)));
    }

    void SetGameDoneEffect(bool isEnabled) {
        var pss = gameDoneEffect.GetComponentsInChildren<ParticleSystem>();

        if (pss != null) {
            gameDoneEffect.SetActive(false);
            gameDoneEffect.SetActive(true);

            foreach (var ps in pss) {
                var emit = ps.emission;
                emit.enabled = isEnabled;
            }
        }
    }
    // ===================================================

    void SpawnRole(bool isRecreate = true) {
        var roleName = isRecreate ? (RoleName)Random.Range(0, _roleCount) : ChineseRestaurantManager.Instance.currentRoleName;
        var t = CommonUtility.InstantiateFrom(ChineseRestaurantResPath.PREFAB_DIR + roleName.ToString(), roleRoot);
        _roleAnimation = t.GetComponent<RoleAnimation>();
        ChineseRestaurantManager.Instance.currentRoleName = roleName;
    }

    void RoleWalk() {
        _roleAnimation.Walk();
        roleWaypointAnimation.ToEnd(() => _roleAnimation.Sit().OnFinished(() => {
            menuAnimation.GetComponent<BoxCollider>().enabled = true;
            InvokeRepeating("MenuShake", 0f, _shakeInterval);
        }));

        StartCoroutine(TimeUtility.DelayInvoke(1f, () => {
            var sfxPaths = new string[] { ChineseRestaurantResPath.LEDI_404040101, ChineseRestaurantResPath.LEDI_404040105 }; 
            _lediAnimation.Greet(sfxPaths[Random.Range(0, sfxPaths.Length)], () => LeDiWalk());
        }));
    }

    void LeDiWalk(bool isLeave = false) {
        _lediAnimation.Walk();

        if (!isLeave) {
            lediWaypointAnimation.ToStep(2, () => _lediAnimation.Idle().OnFinished(() => {
                var paths = new string[] {
                    ChineseRestaurantResPath.LEDI_404040102,
                    ChineseRestaurantResPath.LEDI_404040103,
                    ChineseRestaurantResPath.LEDI_404040104,
                    ChineseRestaurantResPath.LEDI_404040106
                };

                _lediAnimation.Talk(paths[Random.Range(0, paths.Length)]);
            }));
        } else {
            AudioManager.Instance.PlaySound(ChineseRestaurantResPath.LEDI_404040108);
            lediWaypointAnimation.ToEnd(() => {
                _lediAnimation.Idle();
                ChineseRestaurantManager.Instance.ToNextLevel();
            });
        }
    }

    void MenuShake() {
        AudioManager.Instance.PlaySound(ChineseRestaurantResPath.SFX_MENU_SHAKE);
        menuAnimation.Shake();
    }

    public void OnClickMenu(BoxCollider collider) {
        CancelInvoke();
        collider.enabled = false;
        AudioManager.Instance.PlaySound(ChineseRestaurantResPath.SFX_MENU_PAGE_CLICK);

        menuAnimation.Idle().OnFinished(
            () => cameraAnimation.Forward().OnFinished(
                () => menuAnimation.Open().OnFinished(
                    () => {
                        uiRoot.SetActive(true);
                        menuAnimation.ButtonShowHide(_btnLeft, _btnRight);
                    })));
    }

    // 选中指定的菜品后停留的时长，在此时长内可以重新选择菜品
    float _selectDuration = 2f;
    MeshRenderer _pageLeftMR;
    MeshRenderer _pageRightMR;
    DishName? _lastDishName = null;

    public void OnClickPageLeft(MeshRenderer render) {
        RestMenuSelectState();
        _pageLeftMR = render;
        var dishName = menuAnimation.ClickPageLeft(render);

        if (dishName == null || _lastDishName == dishName) {
            return;
        }

        _lastDishName = dishName;
        AudioManager.Instance.StopAllSound();
        _roleAnimation.Nod(ChineseRestaurantManager.Instance.GetVoicePathFrom(RoleState.OrderDishes), true);

        StartCoroutine(TimeUtility.DelayInvoke(_selectDuration, () => {
            uiRoot.SetActive(false);
            menuAnimation.Close(ChineseRestaurantResPath.SFX_MENU_CLOSE).OnFinished(() => cameraAnimation.Reverse().OnFinished(() => LeDiWalk(true)));
        }));

        AudioManager.Instance.PlaySound(ChineseRestaurantResPath.SFX_MENU_PAGE_CLICK);       
    }

    public void OnClickPageRight(MeshRenderer render) {
        RestMenuSelectState();
        _pageRightMR = render;
        var dishName = menuAnimation.ClickPageRight(render);

        if (dishName == null || _lastDishName == dishName) {
            return;
        }

        _lastDishName = dishName;
        AudioManager.Instance.StopAllSound();
        _roleAnimation.Nod(ChineseRestaurantManager.Instance.GetVoicePathFrom(RoleState.OrderDishes), true);

        StartCoroutine(TimeUtility.DelayInvoke(_selectDuration, () => {
            uiRoot.SetActive(false);
            menuAnimation.Close(ChineseRestaurantResPath.SFX_MENU_CLOSE).OnFinished(() => cameraAnimation.Reverse().OnFinished(() => LeDiWalk(true)));
        }));

        AudioManager.Instance.PlaySound(ChineseRestaurantResPath.SFX_MENU_PAGE_CLICK);
    }

    public void OnClickButtonLeft() {
        RestMenuSelectState();
        menuAnimation.ClickButtonLeft(_btnLeft, _btnRight);
        AudioManager.Instance.PlaySound(ChineseRestaurantResPath.SFX_MENU_FLIP);
    }

    public void OnClickButtonRight() {
        RestMenuSelectState();
        menuAnimation.ClickButtonRight(_btnLeft, _btnRight);
        AudioManager.Instance.PlaySound(ChineseRestaurantResPath.SFX_MENU_FLIP);
    }

    void RestMenuSelectState() {
        StopAllCoroutines();

        if (_pageLeftMR) {
            _pageLeftMR.enabled = false;
        }

        if (_pageRightMR) {
            _pageRightMR.enabled = false;
        }
    }
}
